/*
 * This source code is part of TWaver 4.0
 *
 * Serva Software PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * Copyright 2002 - 2011 Serva Software. All rights reserved.
 */

package demo.table.person;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JSplitPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;

import twaver.Element;
import twaver.SendToBottomFilter;
import twaver.SendToTopFilter;
import twaver.TDataBox;
import twaver.TUIManager;
import twaver.TWaverConst;
import twaver.TWaverUtil;
import twaver.VisibleFilter;
import twaver.swing.TableLayout;
import twaver.table.Category;
import twaver.table.TElementTable;
import twaver.table.TPropertySheet;
import twaver.table.TPropertySheetPane;
import twaver.table.TTableColumn;
import twaver.table.TTableModel;
import demo.DemoPane;

public class PersonDemo extends DemoPane {

	static{
		Category.registerCategory("bo", "Business Object");
		
		Category.registerCategory("ejb", "Element JavaBean");
		Category.registerCategory("ecp", "Element ClientProperty");
		Category.registerCategory("eup", "Element UserProperty");
        
		Category.registerCategory("bjb", "Business JavaBean");
		Category.registerCategory("bnd", "Business NestedData");
		Category.registerCategory("bcp", "Business ClientProperty");
	}
	
	private TDataBox box = new TDataBox();
	private TElementTable table;
	private Font font = TWaverUtil.getFont(Font.BOLD | Font.ITALIC, 12);
	private Color alternateColor = new Color(238, 238, 238);
	private Color tableHeaderColor = new Color(99, 130, 191);
	private JRadioButton alternateButton = new JRadioButton("Alternate", false);
	private JRadioButton gradientButton = new JRadioButton("Gradient", true);
	
	public PersonDemo(){		
		table = new PersonTable(box){
			public void prepareTableHeaderRenderer(JLabel renderer, TTableColumn tableColumn){
				renderer.setOpaque(false);
				renderer.setForeground(Color.white);
				renderer.setFont(font);
			}
			public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
				Component component = super.prepareRenderer(renderer, row, col);
				if(alternateButton.isSelected()){
					setAlternateRowColor(component, row, col);
				}else{
					setGradientRowColor(component, row, col);
				}
				Person person = (Person) table.getElementByRowIndex(row);
				if(person != null && !person.isSelected()){
					if(person.getAge() == 20 || person.getAge() == 80){
						component.setBackground(Color.green);
					}
				}
				return component;
			}
			public boolean isCellEditable(int row, int col) {
				TTableColumn column = this.getColumnByIndex(col);
				if(column.getName().equals(TWaverConst.USER_PROPERTY_PREFIX + "MultiLine")){
					return true;
				}
				return super.isCellEditable(row, col);
			}
			
		    protected JTableHeader createDefaultTableHeader() {
		        return new JTableHeader(columnModel){
					public void paintComponent(Graphics g) {
						this.setOpaque(false);
						Graphics2D g2 = (Graphics2D)g;
			            g2.setPaint(new GradientPaint(0, this.getHeight()/4, Color.black, 0, this.getHeight()/7*6, tableHeaderColor, true));
			            g2.fillRect(0, 0, table.getWidth(), this.getHeight());
			            super.paintComponent(g);
					}
				};
		    }			
		};
		
		table.setElementClass(Person.class);
		table.setEditable(false);
		table.getTableModel().sortColumn("age", TTableModel.SORT_DESCENDING);
		
		PersonDataFactory.initBox(table, box, 500);
		
		final JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 100, 0);
		slider.setPaintLabels(true);
		slider.setPaintTicks(true);
		slider.setMinorTickSpacing(1);
		slider.setMajorTickSpacing(10);
		slider.setSnapToTicks(true);
		
		TPropertySheet sheet = new PersonSheet(box);
		
    	double[] rows = new double[] {
        	TableLayout.PREFERRED,
    	};
        double[] columns = new double[] {
        	TableLayout.FILL,
            TableLayout.PREFERRED,
            TableLayout.PREFERRED,
        };
        TableLayout layout = new TableLayout(columns, rows);
        layout.setVGap(10);
        layout.setHGap(3);
        JPanel topPanel = new JPanel(layout);
		topPanel.add(slider, "0,0");
		topPanel.add(gradientButton, "1,0");
		topPanel.add(alternateButton, "2,0");
		
		ActionListener l = new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				table.repaint();
			}
		};
		ButtonGroup group = new ButtonGroup();
		group.add(gradientButton);
		group.add(alternateButton);	
		gradientButton.addActionListener(l);
		alternateButton.addActionListener(l);
		
		final JPanel leftPanel = new JPanel(new BorderLayout());
		leftPanel.add(topPanel, BorderLayout.NORTH);
		JScrollPane scrollPane = new JScrollPane(table);
		leftPanel.add(scrollPane, BorderLayout.CENTER);		
		
		JSplitPane split = new JSplitPane();
		split.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
		split.setContinuousLayout(true);
		split.add(leftPanel, JSplitPane.TOP);
		split.add(new TPropertySheetPane(sheet), JSplitPane.BOTTOM);
		split.setDividerLocation(450);

		Element element = box.getElementByID("(505)");
		box.getSelectionModel().setSelection(element);
		this.add(split, BorderLayout.CENTER);
		this.add(table.getCategoryVisiblePanel(), BorderLayout.SOUTH);
		
		slider.addChangeListener(new ChangeListener(){
			public void stateChanged(ChangeEvent e) {
				table.getTableModel().publishData();
			}
		});

		table.addVisibleFilter(new VisibleFilter(){
			public boolean isVisible(Element element) {
				Person person = (Person)element;
				return person.getAge() >= slider.getValue();
			}
		});
		table.setSendToTopFilter(new SendToTopFilter(){
			public boolean isSendToToppable(Element element) {
				Person person = (Person)element;
				return person.getAge() == 20;
			}
		});		
		table.setSendToBottomFilter(new SendToBottomFilter(){
			public boolean isSendToBottomable(Element element) {
				Person person = (Person)element;
				return person.getAge() == 80;
			}
		});			
		table.addElementDoubleClickedActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				Person person = (Person)e.getSource();
				JOptionPane.showMessageDialog(leftPanel,
						"<html>I am <font color=blue><b>" + person.getFullName() + "</b></font>"
						+ " at <font color=red><b>" + person.getAge() + "</b></font> years </html>");	
			}
		});
	}

	public void setGradientRowColor(Component component, int row, int col){
		if (component instanceof JComponent) {
			JComponent comp = (JComponent) component;
			comp.setOpaque(true);
			Person person = (Person) table.getElementByRowIndex(row);
			if(person == null){
				return;
			}
			int blueValue = 255 - (person.getAge() * 2);
			TTableColumn column = (TTableColumn) table.getColumnByIndex(col);
			if (column.getName().equals("age")) {
				if (!person.isSelected()) {
					comp.setBackground(new Color(255, blueValue, 255));
				}
			} 
			else if(!column.getDisplayName().equals("Severity")){
				if (!person.isSelected()) {
					comp.setBackground(new Color(255, 255, blueValue));
				}
			}
			if (column.getName().equals("fullName")) {
				comp.setFont(font);
				comp.setForeground(Color.BLUE);
			}
			else{
				comp.setFont(TUIManager.getDefaultPlainFont());
				comp.setForeground(Color.BLACK);
			}
		}
	}
	
	public void setAlternateRowColor(Component component, int row, int col){
		Person person = (Person) table.getElementByRowIndex(row);
		if(person == null){
			return;
		}
		TTableColumn column = (TTableColumn) table.getColumnByIndex(col);
		if(!column.getDisplayName().equals("Severity") && !person.isSelected()){
            if (row % 2 == 0) {
            	component.setBackground(alternateColor);
            } else {
            	component.setBackground(Color.WHITE);
            }
		}
	}

}